#include "TaskQueue.h"

TaskQueue::TaskQueue(size_t capa)
: _capacity(capa)
, _que()
, _mutex()
, _notEmpty()
, _notFull()
{
}

TaskQueue::~TaskQueue()
{

}

//生产数据与消费数据
void TaskQueue::push(const int &value)
{
    //1、先上锁
    /* _mutex.lock(); */
    //unique_loc会使用RAII的思想，利用栈对象的生命周期管理资源
    unique_lock<mutex> ul(_mutex);//上锁
    //2、判满
    /* if(full())//虚假唤醒的 */
    while(full())//为了解决虚假唤醒的问题，可以将if改为while循环
    {
        //2.1、如果发现仓库是满的，睡眠
        //wait函数的底层会：先解锁（释放锁），然后睡眠(解锁与睡眠是原子的)
        //在被唤醒之后，要：先抢锁、最后返回(抢到才能返回)
        _notFull.wait(ul);
    }
    //2.2、如果不满，就可以将数据存放在仓库中（也就是数据成员queue中）
    //然后唤醒消费者
    _que.push(value);
    _notEmpty.notify_one();
    //-1, 最后解锁
    /* _mutex.unlock(); */
}

int TaskQueue::pop()
{
    unique_lock<mutex> ul(_mutex);//上锁
    while(empty())
    {
        _notEmpty.wait(ul);
    }
    int tmp = _que.front();//获取元素
    _que.pop();//然后删除
    _notFull.notify_one();

    return tmp;
}

//判空与判满
bool TaskQueue::empty() const
{
    return 0 == _que.size();
}

bool TaskQueue::full() const
{
    return _capacity == _que.size();
}
